home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJINC106.ARJ / FIX16.H < prev    next >
C/C++ Source or Header  |  1992-03-29  |  13KB  |  638 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
  5.     adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
  6.  
  7. This file is part of the GNU C++ Library.  This library is free
  8. software; you can redistribute it and/or modify it under the terms of
  9. the GNU Library General Public License as published by the Free
  10. Software Foundation; either version 2 of the License, or (at your
  11. option) any later version.  This library is distributed in the hope
  12. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  13. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14. PURPOSE.  See the GNU Library General Public License for more details.
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #ifndef _Fix16_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #endif
  24. #define _Fix16_h 1
  25.  
  26. #include <stream.h>
  27. #include <std.h>
  28.  
  29. // constant definitions
  30.  
  31. #define Fix16_fs     ((double)((unsigned)(1 << 15)))
  32.  
  33. #define Fix16_msb    (1 << 15)
  34. #define Fix16_m_max    ((1 << 15) - 1)
  35. #define Fix16_m_min    ((short)(1 << 15))
  36.  
  37. #define Fix16_mult    Fix16_fs
  38. #define Fix16_div    (1./Fix16_fs)
  39. #define Fix16_max    (1. - .5/Fix16_fs)
  40. #define Fix16_min    (-1.)
  41.  
  42.  
  43. #define Fix32_fs     ((double)((unsigned long)(1 << 31)))
  44.  
  45. #define Fix32_msb    ((unsigned long)(1 << 31))
  46. #define Fix32_m_max    ((1 << 31) - 1)
  47. #define Fix32_m_min    ((long)(1 << 31))
  48.  
  49. #define Fix32_mult    Fix32_fs
  50. #define Fix32_div    (1./Fix32_fs)
  51. #define Fix32_max    (1. - .5/Fix32_fs)
  52. #define Fix32_min    (-1.)
  53.  
  54.  
  55. //
  56. // Fix16    class: 16-bit Fixed point data type
  57. //
  58. //    consists of a 16-bit mantissa (sign bit & 15 data bits).
  59. //
  60.  
  61. class Fix16 
  62.   friend class          Fix32;
  63.  
  64.   short                 m;
  65.  
  66.   short                 round(double d);
  67.   short                 assign(double d);
  68.                         Fix16(short i);
  69.                         Fix16(int i);
  70.  
  71.          operator       double();
  72.  
  73.  
  74. public:
  75.                         Fix16();
  76.                         Fix16(Fix16&  f);
  77.                         Fix16(double d);
  78.                         Fix16(Fix32& f);
  79.  
  80.                         ~Fix16();
  81.  
  82.   Fix16&                operator=(Fix16&  f);
  83.   Fix16&                operator=(double d);
  84.   Fix16&                operator=(Fix32& f);
  85.  
  86.   friend short&         mantissa(Fix16&  f);
  87.   friend double         value(Fix16&  f);
  88.  
  89.   Fix16                 operator +  ();
  90.   Fix16                 operator -  ();
  91.  
  92.   friend Fix16          operator +  (Fix16&  f, Fix16&  g);
  93.   friend Fix16          operator -  (Fix16&  f, Fix16&  g);
  94.   friend Fix32          operator *  (Fix16&  f, Fix16&  g);
  95.   friend Fix16          operator /  (Fix16&  f, Fix16&  g);
  96.   friend Fix16          operator << (Fix16&  f, int b);
  97.   friend Fix16          operator >> (Fix16&  f, int b);
  98.  
  99.   Fix16&                operator += (Fix16&  f);
  100.   Fix16&                operator -= (Fix16&  f);
  101.   Fix16&                operator *= (Fix16& );
  102.   Fix16&                operator /= (Fix16&  f);
  103.   
  104.   Fix16&                operator <<=(int b);
  105.   Fix16&                operator >>=(int b);
  106.  
  107.   friend int            operator == (Fix16&  f, Fix16&  g);
  108.   friend int            operator != (Fix16&  f, Fix16&  g);
  109.   friend int            operator >= (Fix16&  f, Fix16&  g);
  110.   friend int            operator <= (Fix16&  f, Fix16&  g);
  111.   friend int            operator >  (Fix16&  f, Fix16&  g);
  112.   friend int            operator <  (Fix16&  f, Fix16&  g);
  113.  
  114.   friend istream&       operator >> (istream& s, Fix16&  f);
  115.   friend ostream&       operator << (ostream& s, Fix16&  f);
  116.  
  117.   void                  overflow(short&);
  118.   void                  range_error(short&);
  119.  
  120.   friend Fix16          operator *  (Fix16&  f, int g);
  121.   friend Fix16          operator *  (int g, Fix16&  f);
  122.   Fix16&                operator *= (int g);
  123. };
  124.  
  125.  
  126. //
  127. // Fix32 class: 32-bit Fixed point data type
  128. //
  129. //    consists of a 32-bit mantissa (sign bit & 31 data bits).
  130. //
  131.  
  132. class Fix32 
  133.   friend class         Fix16;
  134.  
  135.   long                 m;
  136.  
  137.   long                 round(double d);
  138.   long                 assign(double d);
  139.  
  140.                        Fix32(long i);
  141.                        operator double();
  142.  
  143.  
  144. public:
  145.                        Fix32();
  146.                        Fix32(Fix32& f);
  147.                        Fix32(Fix16&  f);
  148.                        Fix32(double d);
  149.                        ~Fix32();
  150.  
  151.   Fix32&               operator =  (Fix32& f);
  152.   Fix32&               operator =  (Fix16&  f);
  153.   Fix32&               operator =  (double d);
  154.  
  155.   friend long&         mantissa(Fix32& f);
  156.   friend double        value(Fix32& f);
  157.  
  158.   Fix32                operator +  ();
  159.   Fix32                operator -  ();
  160.  
  161.   friend Fix32         operator +  (Fix32& f, Fix32& g);
  162.   friend Fix32         operator -  (Fix32& f, Fix32& g);
  163.   friend Fix32         operator *  (Fix32& f, Fix32& g);
  164.   friend Fix32         operator /  (Fix32& f, Fix32& g);
  165.   friend Fix32         operator << (Fix32& f, int b);
  166.   friend Fix32         operator >> (Fix32& f, int b);
  167.  
  168.   friend Fix32         operator *  (Fix16&  f, Fix16&  g);
  169.  
  170.   Fix32&               operator += (Fix32& f);
  171.   Fix32&               operator -= (Fix32& f);
  172.   Fix32&               operator *= (Fix32& f);
  173.   Fix32&               operator /= (Fix32& f);
  174.   Fix32&               operator <<=(int b);
  175.   Fix32&               operator >>=(int b);
  176.  
  177.   friend int           operator == (Fix32& f, Fix32& g);
  178.   friend int           operator != (Fix32& f, Fix32& g);
  179.   friend int           operator >= (Fix32& f, Fix32& g);
  180.   friend int           operator <= (Fix32& f, Fix32& g);
  181.   friend int           operator >  (Fix32& f, Fix32& g);
  182.   friend int           operator <  (Fix32& f, Fix32& g);
  183.  
  184.   friend istream&      operator >> (istream& s, Fix32& f);
  185.   friend ostream&      operator << (ostream& s, Fix32& f);
  186.  
  187.   void                 overflow(long& i);
  188.   void                 range_error(long& i);
  189.  
  190.   friend Fix32          operator *  (Fix32&  f, int g);
  191.   friend Fix32          operator *  (int g, Fix32&  f);
  192.   Fix32&                operator *= (int g);
  193. };
  194.  
  195. // active error handler declarations
  196.  
  197. typedef void (*Fix16_peh)(short&);
  198. typedef void (*Fix32_peh)(long&);
  199.  
  200. extern Fix16_peh Fix16_overflow_handler;
  201. extern Fix32_peh Fix32_overflow_handler;
  202.  
  203. extern Fix16_peh Fix16_range_error_handler;
  204. extern Fix32_peh Fix32_range_error_handler;
  205.  
  206. #if defined(SHORT_NAMES) || defined(VMS)
  207. #define    set_overflow_handler    sohndl
  208. #define set_range_error_handler    srnghdl
  209. #endif
  210.  
  211.  
  212. // error handler declarations
  213.  
  214. extern Fix16_peh set_Fix16_overflow_handler(Fix16_peh);
  215. extern Fix32_peh set_Fix32_overflow_handler(Fix32_peh);
  216. extern void set_overflow_handler(Fix16_peh, Fix32_peh);
  217.  
  218. extern Fix16_peh set_Fix16_range_error_handler(Fix16_peh);
  219. extern Fix32_peh set_Fix32_range_error_handler(Fix32_peh);
  220. extern void set_range_error_handler(Fix16_peh, Fix32_peh);
  221.  
  222. extern void
  223.   Fix16_ignore(short&),
  224.   Fix16_overflow_saturate(short&),
  225.   Fix16_overflow_warning_saturate(short&),
  226.   Fix16_warning(short&),
  227.   Fix16_abort(short&);
  228.  
  229. extern void
  230.   Fix32_ignore(long&),
  231.   Fix32_overflow_saturate(long&),
  232.   Fix32_overflow_warning_saturate(long&),
  233.   Fix32_warning(long&),
  234.   Fix32_abort(long&);
  235.  
  236.  
  237. inline Fix16::~Fix16() {}
  238.  
  239. inline short Fix16::round(double d)
  240.   return short( (d >= 0)? d + 0.5 : d - 0.5); 
  241. }
  242.  
  243. inline Fix16::Fix16(short i)        
  244.   m = i; 
  245. }
  246.  
  247. inline Fix16::Fix16(int i)        
  248.   m = i; 
  249. }
  250.  
  251. inline Fix16::operator double() 
  252.   return  Fix16_div * m; 
  253. }
  254.  
  255. inline Fix16::Fix16()                 
  256.   m = 0; 
  257. }
  258.  
  259. inline Fix16::Fix16(Fix16&  f)        
  260.   m = f.m; 
  261. }
  262.  
  263. inline Fix16::Fix16(double d)        
  264. {
  265.   m = assign(d);
  266. }
  267.  
  268.  
  269. inline Fix16&  Fix16::operator=(Fix16&  f)    
  270.   m = f.m; 
  271.   return *this; 
  272. }
  273.  
  274. inline Fix16&  Fix16::operator=(double d) 
  275.   m = assign(d); 
  276.   return *this; 
  277. }
  278.  
  279.  
  280. inline Fix32::Fix32()                
  281.   m = 0;
  282. }
  283.  
  284. inline Fix32::Fix32(long i)        
  285.   m = i;
  286. }
  287.  
  288. inline Fix32:: operator double()        
  289.   return Fix32_div * m;
  290. }
  291.  
  292.  
  293. inline Fix32::Fix32(Fix32& f)        
  294.   m = f.m;
  295. }
  296.  
  297. inline Fix32::Fix32(Fix16&  f)    
  298.   m = long(f.m) << 16;
  299. }
  300.  
  301. inline Fix32::Fix32(double d)        
  302.   m = assign(d);
  303. }
  304.  
  305. inline Fix16::Fix16(Fix32& f)        
  306.   m = f.m >> 16; 
  307. }
  308.  
  309.  
  310. inline Fix16&  Fix16::operator=(Fix32& f)
  311.   m = f.m >> 16; 
  312.   return *this; 
  313. }
  314.  
  315. inline Fix32& Fix32::operator=(Fix32& f)    
  316.   m = f.m;
  317.   return *this; 
  318. }
  319.  
  320. inline Fix32& Fix32::operator=(Fix16&  f)    
  321.   m = long(f.m) << 16;
  322.   return *this;
  323. }
  324.  
  325. inline Fix32& Fix32::operator=(double d)    
  326.   m = assign(d);
  327.   return *this; 
  328. }
  329.  
  330. inline short& mantissa(Fix16&  f)    
  331.   return f.m; 
  332. }
  333.  
  334. inline double value(Fix16&  f)        
  335.   return double(f); 
  336. }
  337.  
  338. inline Fix16 Fix16::operator+()         
  339.   return m; 
  340. }
  341.  
  342. inline Fix16 Fix16::operator-()         
  343.   return -m; 
  344. }
  345.  
  346. inline Fix16 operator+(Fix16&  f, Fix16&  g) 
  347. {
  348.   short sum = f.m + g.m;
  349.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix16_msb )
  350.     f.overflow(sum);
  351.   return sum;
  352. }
  353.  
  354. inline Fix16 operator-(Fix16&  f, Fix16&  g) 
  355. {
  356.   short sum = f.m - g.m;
  357.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix16_msb )
  358.     f.overflow(sum);
  359.   return sum;
  360. }
  361.  
  362. inline Fix32 operator*(Fix16&  f, Fix16&  g)
  363.   return Fix32( long( long(f.m) * long(g.m) << 1)); 
  364. }
  365.  
  366. inline Fix16 operator<<(Fix16& a, int b)     
  367.   return a.m << b; 
  368. }
  369.  
  370. inline Fix16 operator>>(Fix16& a, int b)     
  371.   return a.m >> b; 
  372. }
  373.  
  374. inline  Fix16&  Fix16:: operator+=(Fix16&  f)
  375.   return *this = *this + f; 
  376. }
  377.  
  378. inline Fix16&  Fix16:: operator-=(Fix16&  f)     
  379.   return *this = *this - f; 
  380. }
  381.  
  382. inline Fix16& Fix16::operator*=(Fix16& f)     
  383.   return *this = *this * f; 
  384. }
  385.  
  386. inline Fix16&  Fix16:: operator/=(Fix16&  f)     
  387.   return *this = *this / f; 
  388. }
  389.  
  390. inline Fix16&  Fix16:: operator<<=(int b)    
  391.   return *this = *this << b;
  392. }
  393.  
  394. inline Fix16&  Fix16:: operator>>=(int b)    
  395.   return *this = *this >> b;
  396. }
  397.  
  398. inline int operator==(Fix16&  f, Fix16&  g)    
  399.   return f.m == g.m;
  400. }
  401.  
  402. inline int operator!=(Fix16&  f, Fix16&  g)    
  403.   return f.m != g.m;
  404. }
  405.  
  406. inline int operator>=(Fix16&  f, Fix16&  g)    
  407.   return f.m >= g.m;
  408. }
  409.  
  410. inline int operator<=(Fix16&  f, Fix16&  g)    
  411.   return f.m <= g.m;
  412. }
  413.  
  414. inline int operator>(Fix16&  f, Fix16&  g)    
  415.   return f.m > g.m;
  416. }
  417.  
  418. inline int operator<(Fix16&  f, Fix16&  g)    
  419.   return f.m < g.m;
  420. }
  421.  
  422. inline istream&  operator>>(istream& s, Fix16&  f)
  423.   double d;
  424.   s >> d; 
  425.   f = d; 
  426.   return s; 
  427. }
  428.  
  429. inline ostream&  operator<<(ostream& s, Fix16&  f)
  430.   return s << double(f);
  431. }
  432.  
  433.  
  434. inline Fix16 operator*(Fix16&  f, int g)
  435. {
  436.   return Fix16(short(f.m * g));
  437. }
  438.  
  439. inline Fix16 operator*(int g, Fix16&  f)
  440. {
  441.   return f * g;
  442. }
  443.  
  444.  
  445. inline Fix16& Fix16::operator*=(int g)
  446. {
  447.   return *this = *this * g;
  448. }
  449.  
  450. inline Fix32::~Fix32() {}
  451.  
  452. inline long Fix32::round(double d)
  453.   return long( (d >= 0)? d + 0.5 : d - 0.5);
  454. }
  455.  
  456.  
  457. inline long& mantissa(Fix32& f)    
  458.   return f.m;
  459. }
  460.  
  461. inline double value(Fix32& f)        
  462.   return double(f);
  463. }
  464.  
  465. inline Fix32 Fix32::operator+()         
  466.   return m;
  467. }
  468.  
  469. inline Fix32 Fix32::operator-()         
  470.   return -m;
  471. }
  472.  
  473. inline Fix32 operator+(Fix32& f, Fix32& g) 
  474. {
  475.   long sum = f.m + g.m;
  476.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix32_msb )
  477.     f.overflow(sum);
  478.   return sum;
  479. }
  480.  
  481. inline Fix32 operator-(Fix32& f, Fix32& g) 
  482. {
  483.   long sum = f.m - g.m;
  484.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix32_msb )
  485.     f.overflow(sum);
  486.   return sum;
  487. }
  488.  
  489. inline Fix32 operator<<(Fix32& a, int b)     
  490.   return a.m << b;
  491. }
  492.  
  493. inline Fix32 operator>>(Fix32& a, int b)     
  494.   return a.m >> b;
  495. }
  496.  
  497. inline Fix32& Fix32::operator+=(Fix32& f)     
  498.   return *this = *this + f;
  499. }
  500.  
  501. inline Fix32& Fix32::operator-=(Fix32& f)     
  502.   return *this = *this - f;
  503. }
  504.  
  505. inline Fix32& Fix32::operator*=(Fix32& f)     
  506.   return *this = *this * f;
  507. }
  508.  
  509. inline Fix32& Fix32::operator/=(Fix32& f)     
  510.   return *this = *this / f;
  511. }
  512.  
  513.  
  514. inline Fix32& Fix32::operator<<=(int b)    
  515.   return *this = *this << b;
  516. }
  517.  
  518. inline Fix32& Fix32::operator>>=(int b)    
  519.   return *this = *this >> b;
  520. }
  521.  
  522. inline int operator==(Fix32& f, Fix32& g)    
  523.   return f.m == g.m;
  524. }
  525.  
  526. inline int operator!=(Fix32& f, Fix32& g)    
  527.   return f.m != g.m;
  528. }
  529.  
  530. inline int operator>=(Fix32& f, Fix32& g)    
  531.   return f.m >= g.m;
  532. }
  533.  
  534. inline int operator<=(Fix32& f, Fix32& g)    
  535.   return f.m <= g.m;
  536. }
  537.  
  538. inline int operator>(Fix32& f, Fix32& g)    
  539.   return f.m > g.m;
  540. }
  541.  
  542. inline int operator<(Fix32& f, Fix32& g)    
  543.   return f.m < g.m;
  544. }
  545.  
  546. inline istream& operator>>(istream& s, Fix32& f)
  547.   double d;
  548.   s >> d; 
  549.   f = d; 
  550.   return s; 
  551. }
  552.  
  553. inline ostream& operator<<(ostream& s, Fix32& f)
  554.   return s << double(f);
  555. }
  556.  
  557. inline Fix32 operator*(Fix32&  f, int g)
  558. {
  559.   return Fix32(long(f.m * g));
  560. }
  561.  
  562. inline Fix32 operator*(int g, Fix32&  f)
  563. {
  564.   return f * g;
  565. }
  566.  
  567.  
  568.  
  569. inline Fix32& Fix32::operator*=(int g)
  570. {
  571.   return *this = *this * g;
  572. }
  573.  
  574. #endif
  575.